#ifndef OneButton_h
#define OneButton_h

#include "ebox_core.h"


// -----
// OneButton.h - Library for detecting button clicks, doubleclicks and long
// press pattern on a single button. This class is implemented for use with the
// Arduino environment. Copyright (c) by Matthias Hertel,
// http://www.mathertel.de This work is licensed under a BSD style license. See
// http://www.mathertel.de/License.aspx More information on:
// http://www.mathertel.de/Arduino
// -----
// 02.10.2010 created by Matthias Hertel
// 21.04.2011 transformed into a library
// 01.12.2011 include file changed to work with the Arduino 1.0 environment
// 23.03.2014 Enhanced long press functionalities by adding longPressStart and
// longPressStop callbacks
// 21.09.2015 A simple way for debounce detection added.
// 14.05.2017 Debouncing improvements.
// 25.06.2018 Optional third parameter for deactivating pullup.
// 26.09.2018 Anatoli Arkhipenko: Included solution to use library with other
// sources of input.
// 26.09.2018 Initialization moved into class declaration.
// 26.09.2018 Jay M Ericsson: compiler warnings removed.
// 29.01.2020 improvements from ShaggyDog18
// -----



// ----- Callback function types -----

typedef void (*callbackFunction)(void);
typedef void (*parameterizedCallbackFunction)(void *);


typedef enum  {
OCS_INIT = 0,
OCS_DOWN = 1,
OCS_UP = 2,
OCS_COUNT = 3,
OCS_PRESS = 6,
OCS_PRESSEND = 7,
UNKNOWN = 99
}stateMachine_t;
	
typedef struct{
//	PORT_Id_t port;
//	PORT_GpioNum_t num;
    Gpio *p;
	
  unsigned int _debounceTicks; // number of ticks for debounce times.
  unsigned int _clickTicks ;   // number of msecs before a click is detected.
  unsigned int _pressTicks ;   // number of msecs before a long button press is detected
  unsigned int _duringLongPressFuncInterval ;   // number of msecs before a long button press is detected
  unsigned long _duringLongPressFuncLastTime; // start of current input change to checking debouncing

  int _buttonPressed;
  // These variables will hold functions acting as event source.
  callbackFunction _clickFunc;
  callbackFunction _doubleClickFunc;
  callbackFunction _multiClickFunc;
  callbackFunction _longPressStartFunc;
  callbackFunction _longPressStopFunc;
  callbackFunction _duringLongPressFunc;
	
	stateMachine_t _state ;
  stateMachine_t _lastState ; // used for debouncing
  unsigned long _startTime; // start of current input change to checking debouncing
  int _nClicks;             // count the number of clicks with this variable
  int _maxClicks ;       // max number (1, 2, multi=3) of clicks of interest by registration of event functions.
}OneBtn_t;

void ob_init(OneBtn_t *pin, boolean activeLow , bool pullupActive);
void ob_setDebounceTicks(OneBtn_t *pin, int ticks);
void ob_setClickTicks(OneBtn_t *pin, int ticks);
void ob_setPressTicks(OneBtn_t *pin, int ticks);
void ob_attachClick(OneBtn_t *pin, callbackFunction newFunction);
void ob_attachDoubleClick(OneBtn_t *pin, callbackFunction newFunction);
void ob_attachMultiClick(OneBtn_t *pin, callbackFunction newFunction);
void ob_attachLongPressStart(OneBtn_t *pin, callbackFunction newFunction);
void ob_attachLongPressStop(OneBtn_t *pin, callbackFunction newFunction);
void ob_attachDuringLongPress(OneBtn_t *pin, callbackFunction newFunction);
void ob_tick(OneBtn_t *pin);
void ob_tick_l(OneBtn_t *pin, bool activeLevel);
void ob_reset(OneBtn_t *pin);
int ob_getNumberClicks(OneBtn_t *pin);
bool ob_isIdle(OneBtn_t *pin );// const { return _state == OCS_INIT; }
bool ob_isLongPressed(OneBtn_t *pin);// const { return _state == OCS_PRESS; };
void ob_newState(OneBtn_t *pin, stateMachine_t nextState);





#endif
